#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ogcsys.h>

#include "channel.h"
#include "cios.h"

/* Constants */
#define ENTRIES_PER_PAGE	5


static u32  str_maxlen = 0;
u32 gcnt = 0;

channel *temp;


int __Channel_Strcmp(const void *ptr1, const void *ptr2)
{
	const char *str1 = ((channel *)ptr1)->name;
	const char *str2 = ((channel *)ptr2)->name;

	/* Compare strings */
	return strcmp(str1, str2);
}

int __Channel_GetName(u64 tid, char *string)
{
	
	static imet imet_data ATTRIBUTE_ALIGN(32);
	u16   *imet_name = NULL;
	
	tikview *views = NULL;

	u32 cnt, nb_views;
	s32 cfd = -1, ret;
	
	u64 sz ATTRIBUTE_ALIGN(32) = 0x140;
	u8 *data = (u8*)memalign(32, sz);

	

	/* Get number of ticket views */
	ret = ES_GetNumTicketViews(tid, &nb_views);
	if (ret < 0)
		return -1001;

	if (!nb_views)
		return -1011;

	/* Allocate memory */
	views = (tikview *)memalign(32, sizeof(tikview) * nb_views);
	if (!views)
		return -1002;

	/* Get ticket views */
	ret = ES_GetTicketViews(tid, views, nb_views);
	if (ret < 0)
	{
		ret = -1003;
		goto out;
	}

	/* Open content 0 */
	cfd = ES_OpenTitleContent(tid, 0);
	if (cfd < 0) {
		ret = -1004;
		goto out;
	}

	/* Read content */
	ret = ES_ReadContent(cfd, data, sz);
	if (ret < 0)
	{
		free(data);
		ret = -1005;
		goto out;
	}

	
	/* Select channel name (in proper language) */
	ret = CONF_GetLanguage();
	
	int chan_name_offset=0x54;					// Default to English
	if(ret>0)						// Don't show Japanese, because we don't have unicode.
		chan_name_offset=(ret*0x54);

	//switch (ret) {
	/* Japanese */
	//case CONF_LANG_JAPANESE:	imet_name = imet_data.name_jp; break;
	/* German */
	//case CONF_LANG_GERMAN:		imet_name = imet_data.name_de; break;
	/* French */
	//case CONF_LANG_FRENCH:		imet_name = imet_data.name_fr; break;
	/* Spanish */
	//case CONF_LANG_SPANISH:		imet_name = imet_data.name_es; break;
	/* Italian */
	//case CONF_LANG_ITALIAN:		imet_name = imet_data.name_it; break;
	/* Dutch */
	//case CONF_LANG_DUTCH:		imet_name = imet_data.name_nl; break;
	/* Default: English */
	//default:			imet_name = imet_data.name_en;
	//}

	/* No valid IMET name */
	//if (!imet_name[0]) {
		/* Default language: English */
	//	imet_name = imet_data.name_en;

		/* No name, find one */
		//if (!imet_name[0])
			//imet_name = imet_data.name_de;
		//if (!imet_name[0])
//			imet_name = imet_data.name_fr;
		//if (!imet_name[0])
//			imet_name = imet_data.name_es;
		//if (!imet_name[0])
//			imet_name = imet_data.name_it;
		//if (!imet_name[0])
//			imet_name = imet_data.name_nl;
		//if (!imet_name[0])
//			imet_name = imet_data.name_jp;
//	}

	/* Valid name found */
	//if (imet_name[0]) {
		/* Copy channel name */
	//	for (cnt = 0; cnt < CHANNEL_NAME_LEN; cnt++)
	//		string[cnt] = imet_name[cnt];
	//	ret = 0;
	//} else {
	//	ret = -1009;
	//}
	int y = 0;
	for(y=0;y<0x28;y++)
		string[y]=data[(0x9C+chan_name_offset)+(y*2)+1]; //0x54
	for (cnt = 0; cnt < CHANNEL_NAME_LEN; cnt++)
		string[cnt] = data[cnt];



out:
	/* Close content */
	if (cfd >= 0)
		ES_CloseContent(cfd);

	/* Free memory */
	if (views)
		free(views);

	return ret;
}

void Channel_Launch(u32 selected)
{
	tikview *views = NULL;
	u64        tid = channel_list[selected].tid;

	u32 nb_views;
	s32 ret;

	printf("\n");
	printf("[+] Launching title %016llX, please wait...", tid);
	fflush(stdout);

	/* Get number of ticket views */
	ret = ES_GetNumTicketViews(tid, &nb_views);
	if (ret < 0) {
		printf(" ERROR! Could not get number of ticket views! (ret = %d)\n", ret);
		return;
	}

	if (!nb_views) {
		printf(" ERROR! No ticket views! (ret = %d)\n", ret);
		return;
	}

	/* Allocate memory */
	views = (tikview *)memalign(32, sizeof(tikview) * nb_views);
	if (!views)
		return;

	/* Get ticket views */
	ret = ES_GetTicketViews(tid, views, nb_views);
	if (ret < 0) {
		printf(" ERROR! Could not get ticket views! (ret = %d)\n", ret);
		goto err;
	}

	/* Launch title */
	ret = ES_LaunchTitle(tid, &views[0]);
	if (ret < 0)
		printf(" ERROR! Could not launch title! (ret = %d)\n", ret);

err:
	/* Free memory */
	if (views)
		free(views);
}

/*void Channel_MoveList(s8 delta)
{
	s32 index;

	
	if (!channel_list || !channel_cnt)
		return;

	
	selected += delta;

	
	if (selected <= -1)
		selected = (channel_cnt - 1);
	if (selected >= channel_cnt)
		selected = 0;


	index = (selected - start);

	if (index >= ENTRIES_PER_PAGE)
		start += index - (ENTRIES_PER_PAGE - 1);
	if (index <= -1)
		start += index;
}*/
/*
void Channel_PrintList(void)
{
	u32 cnt;

	
	if (!channel_list || !channel_cnt) {
		printf("\t>> No channels found!!\n");
		return;
	}

	for (cnt = start; cnt < channel_cnt; cnt++) {
		channel *p_channel = &channel_list[cnt];

		char *type = "Unknown type";
		u32     id = (u32)(p_channel->tid >> 32);

		
		if ((cnt - start) >= ENTRIES_PER_PAGE)
			break;

		
		switch (id) {
		
		case 0x10001:
			type = "Downloadable channel (VC/WiiWare)";
			break;

		
		case 0x10002:
			type = "System channel";
			break;

		
		case 0x10004:
			type = "Game channel";
			break;
		}

	
		(selected == cnt) ? printf("\t>> ") : printf("\t   ");
		fflush(stdout);


		printf("- %s\n", p_channel->name);


		printf("\t\t\t+ Title Id : %016llx\n", p_channel->tid);
		printf("\t\t\t+ Type     : %s\n", type);

		printf("\n");
	}
}*/

void Channel_FreeList(void)
{
	/* Memory allocated */
	if (channel_list) {
		/* Free memory */
		free(channel_list);

		/* Set pointer to NULL */
		channel_list = NULL;
	}
}

s32 Channel_Gettitle(void)
{

	channel *channels = NULL;
	u64     *titles   = NULL;

	u32 cnt, idx, nb_titles;
	s32 ret;

	/* Free channel list */
	Channel_FreeList();

	/* Get number of titles */
	ret = ES_GetNumTitles(&nb_titles);
	if (ret < 0)
		return -1007;

	/* No titles found */
	if (!nb_titles)
		return -1010;

	/* Allocate memory */
	titles   =     (u64 *)memalign(32, sizeof(u64) * nb_titles);
	channels = (channel *)memalign(32, sizeof(channel) * nb_titles);

	if (!titles || !channels) {
		ret = -1006;
		goto err;
	}

	/* Get title list */
	ret = ES_GetTitles(titles, nb_titles);
	if (ret < 0)
	{
		ret = -1008;
		goto err;
	}

	/* Fill channel array */
	for (cnt = idx = 0; idx < nb_titles; idx++) {
	
		char name[CHANNEL_NAME_LEN] = "Unknown Channel";
		
		u32   id = (u32)(titles[idx] >> 32);
		u64  tid = titles[idx];

		/* Check if title is a channel */
		if (id != 0x10001 && id != 0x10002 && id != 0x10004)
			continue;

		/* Copy title ID */
		channels[cnt].tid = tid;
		
		strcpy(channels[cnt].name, name);
		
		/* Increase counter */
		cnt++;
	}

	/* Set values */
	channel_cnt  = cnt;
	channel_list = channels;
	
	free(titles);

	/* Success */
	ret = 0;

	goto exit;

err:
	if (channels)
		free(channels);
	if (titles)
		free(titles);
		
exit:		

	return ret;
}
